// import store from '@/store'
// import Popup from './cesiumPopup'
// import markerSVG from '../assets/marker-green.png'

// cesium 控制
 let controller = null
 const CesiumController = function(info) {
   if (controller) {
     return controller
   }
   this.constructor(info)
}
CesiumController.prototype.constructor = function(info) {
  // this.ref = info.ref
  controller = this
}

CesiumController.prototype.setCamera = function(camera) {
  this.ref.flyTo(camera)
}

CesiumController.prototype.stopFly = function() {
  // store.dispatch('setCesiumStatus', { key: 'rove', value: false })
  this.ref.flyStop()
}

CesiumController.prototype.flyToViewPoint = function(viewPoint) {
  if (!viewPoint) {
    return
  }
  this.stopFly()
  this.ref.flyToViewPoint(viewPoint)
}

CesiumController.prototype.flyToMarker = function(position) {
  if (!position) {
    return
  }
  this.stopFly()
  this.ref.flyToMarker(position)
}

CesiumController.prototype.startFly = function(pathData) {
  if (!pathData) {
    return
  }
  this.stopFly()
  // store.dispatch('setCesiumStatus', { key: 'rove', value: true })
  this.ref.fly(pathData)
  // store.dispatch('removeCesiumStatus', 'rovePath')
}

// 鼠标悬浮效果
CesiumController.prototype.addMouseOver3DTileFeature = function() {
  viewer = viewer || window.viewer
  viewer.pickTranslucentDepth = true
  const _this = this

  const hovered = {
    feature: undefined,
    originalColor: new Cesium.Color()
  }

  const selected = {
    feature: undefined,
    originalColor: new Cesium.Color()
  }

  const COLOR_HOVERED = Cesium.Color.GREENYELLOW
  const COLOR_SELECTED = Cesium.Color.DEEPSKYBLUE

  // todo 轮廓线会导致黑屏
  // const silhouetteBlue = Cesium.PostProcessStageLibrary.createEdgeDetectionStage()
  // silhouetteBlue.uniforms.color = Cesium.Color.BLUE
  // silhouetteBlue.uniforms.length = 0.005
  // silhouetteBlue.selected = []

  // const silhouetteGreen = Cesium.PostProcessStageLibrary.createEdgeDetectionStage()
  // silhouetteGreen.uniforms.color = Cesium.Color.LIME
  // silhouetteGreen.uniforms.length = 0.01
  // silhouetteGreen.selected = []

  // const silhouette = Cesium.PostProcessStageLibrary.createSilhouetteStage([
  //   silhouetteBlue, silhouetteGreen
  // ])
  // viewer.scene.postProcessStages.add(silhouette)

  // 鼠标移动事件
  viewer.screenSpaceEventHandler.setInputAction(function(movement) {

    if (Cesium.defined(hovered.feature)) {
      // If a feature was previously highlighted, undo the highlight
      if (hovered.feature !== selected.feature) {
        hovered.feature.color = hovered.originalColor
        hovered.feature = undefined
      }

      if (selected.feature && hovered.feature === selected.feature) {
        hovered.feature.color = COLOR_SELECTED
        hovered.feature = selected.feature
      }
    }

    let cartesian = viewer.scene.pickPosition(movement.endPosition) // madd: 将pickPosition方法 提到pick 之前，防止一帧中多次渲染colorBuffer

    // silhouetteGreen.selected = []
    var pickedFeature = viewer.scene.pick(movement.endPosition)
    if (!Cesium.defined(pickedFeature)) {
      _this.closePop()
      return
    }

    // Highlight the feature if it's not already selected.
    hovered.feature = pickedFeature
    Cesium.Color.clone(
      pickedFeature === selected.feature ? selected.originalColor : pickedFeature.color,
      hovered.originalColor
    )
    pickedFeature.color = COLOR_HOVERED


    // let cartesian = viewer.scene.pickPosition(movement.endPosition)
    if (!cartesian) {
      cartesian = pickedFeature.id.cmData.position
    }
    const info = {
      viewer: viewer,
      geometry: cartesian,
      content: pickedFeature
    }
    if (pickedFeature.primitive && viewer) {
      // _this.updatePop(info) // madd: 暂时注释掉业务逻辑代码，该代码不影响闪动，但里面实现需要检查一下
      return
    }
    // _this.closePop()  // madd: 业务逻辑代码，暂时注释，不影响闪动
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)

  // 点击事件
  viewer.screenSpaceEventHandler.setInputAction(function(movement) {
    var pickedFeature = viewer.scene.pick(movement.position)

    // 选中颜色处理
    if (Cesium.defined(selected.feature)) {
      selected.feature.color = selected.originalColor
      selected.feature = undefined
    }
    if (!Cesium.defined(pickedFeature)) {
      return
    }
    console.log(pickedFeature)
    selected.feature = pickedFeature
    Cesium.Color.clone(
      hovered.originalColor,
      selected.originalColor
    )
    pickedFeature.color = Cesium.Color.DEEPSKYBLUE

    // 飞近测点
    const cartesian = viewer.scene.pickPosition(movement.position)
    if (!cartesian) {
      const position = pickedFeature.id.cmData.position
      viewer.camera.flyToBoundingSphere(pickedFeature.id.cmData.boundingSphere)
      setTimeout(() => {
        const info = {
          viewer: viewer,
          geometry: position,
          content: pickedFeature
        }
        if (pickedFeature.primitive) {
          _this.updatePop(info)
        }
      }, 100)

      // 测点弹窗控制
      // store.dispatch('setCesiumWindow', {
      //   type: 'monitor',
      //   id: pickedFeature.id.cmData.deviceId,
      //   name: pickedFeature.id.cmData.name,
      //   show: true
      // })
    } else {
      const type = pickedFeature.getProperty('type')
      if (type) {
        // 设施弹窗控制
        // store.dispatch('setCesiumWindow', {
        //   type: type,
        //   id: pickedFeature.getProperty(`${type}Id`),
        //   name: pickedFeature.getProperty(`${type}Name`),
        //   show: true
        // })
      }
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
}

// 关闭弹窗
CesiumController.prototype.closePop = function() {
  if (this.monitorPop) {
    this.monitorPop.close()
  }
}

// 更新弹窗
CesiumController.prototype.updatePop = function(info) {
  if (!this.monitorPop) {
    this.monitorPop = new Popup(info)
  } else {
    this.monitorPop.updateAll(info)
  }
}

// 撒点
CesiumController.prototype.addMarkersToTiles = function(tiles, data) {
  const entities = []
  const devices = []
  tiles.forEach((tile, index) => {
    let position = null
    if (tile.content._model) {
      // const matrix4 = tile.computedTransform
      // const modelBoundingSphere = tile.content._model.boundingSphere
      // const computedBoundingSphere = Cesium.BoundingSphere.transform(modelBoundingSphere, matrix4)
      // 轮廓效果
      // tile.content._model.silhouetteColor = Cesium.Color.RED
      // tile.content._model.silhouetteSize = 1
      // 显示包围球体
      // tile.content._model.debugShowBoundingVolume = true
      // position = Cesium.Matrix4.multiplyByPoint(tile.content._model.modelMatrix, tile.content._model.boundingSphere.center, new Cesium.Cartesian3())
      // console.log('computed', position)
    } else {
      position = tile.boundingSphere.center
      console.log('tile boundingSphere center', position)
    }

    position = tile.boundingSphere.center
    console.log('tile boundingSphere center', position)

    const pinBuilder = new Cesium.PinBuilder()
    const info = data[index]
    // 测点信息
    devices.push({ deviceId: info.id, type: 'monitor', position: position, boundingSphere: tile.boundingSphere })
    const entity = viewer.entities.add({
      name: info.name,
      cmData: { name: info.name, deviceId: info.id, type: 'monitor', position: position, boundingSphere: tile.boundingSphere },
      position: position,
      billboard: {
        image: pinBuilder.fromColor(Cesium.Color.ROYALBLUE, 48).toDataURL(),
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        // eyeOffset: new Cesium.Cartesian3(0, 0, -100),
        // alignedAxis: Cesium.Cartesian3.ZERO,
        // rotation: 90,
        scale: 0.5,
        disableDepthTestDistance: Number.POSITIVE_INFINITY
      },
      show: true
    })
    entities.push(entity)
  })
  return entities
}

// 删掉撒点
CesiumController.prototype.removeMarkers = function(entities) {
  entities.forEach(entity => {
    viewer.entities.remove(entity)
  })
}

// 删掉所有撒点
CesiumController.prototype.removeAllMarkers = function(entities) {
  viewer.entities.removeAll()
}

// 批量处理
CesiumController.prototype.batchSetting = function(nameList, cb, ...args) {
  const _this = this
  if (!nameList || !nameList.forEach) {
    return
  }
  if (!cb) {
    return
  }
  nameList.forEach(name => {
    const tileset = _this.getTileset(name)
    if (tileset.tilesLoaded) {
      cb(tileset, ...args)
    } else {
      tileset.allTilesLoaded.addEventListener(() => {
        cb(tileset, ...args)
      })
    }
  })
}

// 标记模型设施/设备数据
CesiumController.prototype.setTilesetFeatureProperty = function(tileset, dataList, type = 'structure') {
  // const tiles = tileset._selectedTiles
    const tiles = tileset.selectedTiles // madd: 暂时先使用 public 属性访问，后期会提供更加高效的设置对应modelId 的feature's property 的方法
  for (let i = 0; i < tiles.length; i++) {
    const tile = tiles[i]
    for (let j = 0; j < tile.content.featuresLength; j++) {
      const feature = tile.content.getFeature(j)
      const name = feature.getProperty('name')
      let find = false
      find = dataList.find(data => data.modelId && name.includes(data.modelId))
      if (find) {
        // 设置信息
        feature.setProperty('type', type)
        feature.setProperty(`${type}Id`, find.id)
        feature.setProperty(`${type}Name`, find.name)
      }
    }
  }
}

// 批量标记模型设施/设备数据
CesiumController.prototype.setTilesetsFeatureProperty = function(nameList, structureList, type = 'structure') {
  this.batchSetting(nameList, this.setTilesetFeatureProperty, structureList, type)
}

// 着色
CesiumController.prototype.setTilesetColor = function(tileset, colorData) {
  // const tiles = tileset._selectedTiles
  const tiles = tileset.selectedTiles // madd: 暂时先使用 public 属性访问，后期会提供更加高效的设置对应modelId 的feature's property 的方法
  for (let i = 0; i < tiles.length; i++) {
    const tile = tiles[i]
    for (let j = 0; j < tile.content.featuresLength; j++) {
      const feature = tile.content.getFeature(j)
      const name = feature.getProperty('name')
      // 模型Id
      // const modelId = feature.getProperty('modelIds')
      const modelId = feature.getProperty('modelId') // madd: attention rename modelIds to modelId
      // 遍历颜色
      let findModel = false
      colorData.forEach(item => {
        findModel = item.data.find(_ => modelId === _.modelId)
        feature.setProperty(item.propertyName, !!findModel)
        if (findModel) {
          logFeatureProperties(feature)
          console.log(item.modelId, findModel)
          console.log(item.propertyName, feature.getProperty(item.propertyName))
        }
      })
    }
  }

  const conditions = colorData.map(item => {
    return [`\${${item.propertyName}}`, item.color]
  }).concat([['true', 'color("rgba(255,255,255,1)")']])
  // }).concat([[true, "color('cyan')"]]);

  // const conditions =  [ // madd: test conditions
  //       ["${id} > 100", "color('red')"],
  //       ["${id} > 50", "color('blue')"],
  //       ["${id} > 10", "color('yellow')"],
  //       [true, "color('cyan')"],
  //   ];
  console.log(conditions)
  tileset.style = new Cesium.Cesium3DTileStyle({
    color: {
      conditions: conditions
    },
    anchorLineEnabled: 'true',
    anchorLineColor: 'color("blue")'
    // show: '${Height} > 0',
    // meta: {
    //   description: '"Building id ${id} has height ${Height}."'
    // }
  })
}

// 批量着色
CesiumController.prototype.setTilesetsColor = function(nameList, colorData) {
  this.batchSetting(nameList, this.setTilesetColor, colorData)
}

// 颜色重置
CesiumController.prototype.resetTilesetColor = function(tileset) {
  tileset.style = new Cesium.Cesium3DTileStyle({
    color: {
      conditions: [
        ['true', 'color("rgba(255,255,255,1)")']
      ]
    },
    anchorLineEnabled: 'true',
    anchorLineColor: 'color("blue")'
  })
}

// 批量颜色重置
CesiumController.prototype.resetTilesetsColor = function(nameList) {
  this.batchSetting(nameList, this.resetTilesetColor)
}

// 根据 name 获取 tileset
CesiumController.prototype.getTileset = function(name) {
  for (let i = 0; i < viewer.scene.primitives.length; i++) {
    const item = viewer.scene.primitives.get(i)
    if (item.name === name) {
      // if (!item.ready) return item.readyPromise
      return item
    }
  }
  // return viewer.scene.primitives.get(index)
}

CesiumController.prototype.addTileset = function(tileset) {
  const _tileset = viewer.scene.primitives.add(
    new Cesium.Cesium3DTileset(tileset)
  )
  _tileset.name = tileset.name
  return _tileset
}

// export default CesiumController
